load("@rules_java//java:java_binary.bzl", "java_binary")
load("@rules_java//java:java_library.bzl", "java_library")
load(":javacc_bootstrap.bzl", "javacc_bootstrap")

JAVAC_OPTS = [
    "-XepAllErrorsAsWarnings",
    "-Xep:ComparisonOutOfRange:OFF",
    "-Xep:ChainingConstructorIgnoresParameter:OFF",
    "-Xlint:-dep-ann",
]

JAR_RESOURCES = glob(["src/main/resources/**/*"])

JAVACC_PARSER_SRCS = glob([
    "src/main/java/org/javacc/parser/**/*.java",
    "src/main/java/org/javacc/utils/**/*.java",
])

JTREE_SRCS = glob([
    "src/main/java/org/javacc/jjtree/**/*.java",
])

java_library(
    name = "javacc_version",
    srcs = ["src/main/java/org/javacc/Version.java"],
)

java_library(
    name = "javacc_parser",
    srcs = JAVACC_PARSER_SRCS + [
        ":javacc_stage2_ConditionParser",
        ":javacc_stage2_JavaCC",
    ],
    javacopts = JAVAC_OPTS,
    deps = [":javacc_version"],
)

java_binary(
    name = "javacc",
    srcs = ["src/main/java/javacc.java"],
    javacopts = JAVAC_OPTS,
    main_class = "javacc",
    resources = JAR_RESOURCES,
    visibility = ["//visibility:public"],
    deps = [":javacc_parser"],
)

java_binary(
    name = "jjdoc",
    srcs = ["src/main/java/jjdoc.java"] + glob([
        "src/main/java/org/javacc/jjdoc/**/*.java",
    ]),
    javacopts = JAVAC_OPTS,
    main_class = "jjdoc",
    visibility = ["//visibility:public"],
    deps = [":javacc_parser"],
)

java_binary(
    name = "jjtree",
    srcs = JTREE_SRCS + [
        "src/main/java/jjtree.java",
        ":javacc_stage2_JJTree",
        ":jtree_stage2_JJTree_java",
    ],
    javacopts = JAVAC_OPTS,
    main_class = "jjtree",
    resources = JAR_RESOURCES,
    visibility = ["//visibility:public"],
    deps = [
        ":javacc_parser",
        ":javacc_version",
    ],
)

# javacc bootstrap {{{

JAVACC_JJ_OUTS = [
    "JavaCCParser.java",
    "JavaCCParserConstants.java",
    "JavaCCParserTokenManager.java",
    "JavaCharStream.java",
    "ParseException.java",
    "TokenMgrError.java",
]

CONDITION_PARSER_JJ_OUTS = [
    "ConditionParser.java",
    "ConditionParserConstants.java",
    "ConditionParserTokenManager.java",
    "JavaCharStream.java",
    "ParseException.java",
    "Token.java",
    "TokenMgrError.java",
]

javacc_bootstrap(
    name = "javacc_stage1_JavaCC",
    src = "src/main/javacc/JavaCC.jj",
    outs = JAVACC_JJ_OUTS,
    javacc = "//bootstrap:javacc_stage1",
)

javacc_bootstrap(
    name = "javacc_stage1_ConditionParser",
    src = "src/main/javacc/ConditionParser.jj",
    outs = CONDITION_PARSER_JJ_OUTS,
    javacc = "//bootstrap:javacc_stage1",
)

javacc_bootstrap(
    name = "javacc_stage2_JavaCC",
    src = "src/main/javacc/JavaCC.jj",
    outs = JAVACC_JJ_OUTS,
    javacc = ":javacc_stage2",
)

javacc_bootstrap(
    name = "javacc_stage2_ConditionParser",
    src = "src/main/javacc/ConditionParser.jj",
    outs = CONDITION_PARSER_JJ_OUTS,
    javacc = ":javacc_stage2",
)

java_binary(
    name = "javacc_stage2",
    srcs = JAVACC_PARSER_SRCS + [
        "src/main/java/javacc.java",
        ":javacc_stage1_ConditionParser",
        ":javacc_stage1_JavaCC",
    ],
    javacopts = JAVAC_OPTS,
    main_class = "javacc",
    resources = JAR_RESOURCES,
    deps = [":javacc_version"],
)

# }}}

# jtree bootstrap {{{

JJTREE_JJ_OUTS = [
    "JavaCharStream.java",
    "JJTreeParserConstants.java",
    "JJTreeParser.java",
    "JJTreeParserTokenManager.java",
    "ParseException.java",
    "TokenMgrError.java",
]

JJTREE_JJT_OUTS = [
    "ASTBNFAssignment.java",
    "ASTBNFChoice.java",
    "ASTBNFLookahead.java",
    "ASTBNFNonTerminal.java",
    "ASTBNFOneOrMore.java",
    "ASTBNFParenthesized.java",
    "ASTBNFSequence.java",
    "ASTBNFTryBlock.java",
    "ASTBNFZeroOrMore.java",
    "ASTBNFZeroOrOne.java",
    "ASTCharDescriptor.java",
    "ASTPrimaryExpression.java",
    "ASTProductions.java",
    "ASTRECharList.java",
    "ASTREChoice.java",
    "ASTREEOF.java",
    "ASTRE.java",
    "ASTRENamed.java",
    "ASTREOneOrMore.java",
    "ASTREParenthesized.java",
    "ASTREReference.java",
    "ASTRESequence.java",
    "ASTRESpec.java",
    "ASTREStringLiteral.java",
    "ASTREZeroOrMore.java",
    "ASTREZeroOrOne.java",
    "ASTRRepetitionRange.java",
    "ASTTokenDecls.java",
    "JJTJJTreeParserState.java",
    "JJTreeParserTreeConstants.java",
    "Node.java",
    "SimpleNode.java",
]

javacc_bootstrap(
    name = "jtree_stage1_JJTree",
    src = "src/main/jjtree/JJTree.jjt",
    outs = ["JJTree.jj"] + JJTREE_JJT_OUTS,
    javacc = "//bootstrap:jjtree_stage1",
)

filegroup(
    name = "jtree_stage1_JJTree_java",
    srcs = [":jtree_stage1_JJTree"],
    output_group = "java_files",
)

filegroup(
    name = "jtree_stage1_JJTree_jj",
    srcs = [":jtree_stage1_JJTree"],
    output_group = "jj_files",
)

javacc_bootstrap(
    name = "javacc_stage1_JJTree",
    src = ":jtree_stage1_JJTree_jj",
    outs = JJTREE_JJ_OUTS,
    javacc = ":javacc",
)

java_binary(
    name = "jjtree_stage2",
    srcs = JTREE_SRCS + [
        "src/main/java/jjtree.java",
        ":javacc_stage1_JJTree",
        ":jtree_stage1_JJTree_java",
    ],
    javacopts = JAVAC_OPTS,
    main_class = "jjtree",
    resources = JAR_RESOURCES,
    deps = [
        ":javacc_parser",
        ":javacc_version",
    ],
)

javacc_bootstrap(
    name = "jtree_stage2_JJTree",
    src = "src/main/jjtree/JJTree.jjt",
    outs = ["JJTree.jj"] + JJTREE_JJT_OUTS,
    javacc = ":jjtree_stage2",
)

filegroup(
    name = "jtree_stage2_JJTree_java",
    srcs = [":jtree_stage2_JJTree"],
    output_group = "java_files",
)

filegroup(
    name = "jtree_stage2_JJTree_jj",
    srcs = [":jtree_stage2_JJTree"],
    output_group = "jj_files",
)

javacc_bootstrap(
    name = "javacc_stage2_JJTree",
    src = ":jtree_stage2_JJTree_jj",
    outs = JJTREE_JJ_OUTS,
    javacc = ":javacc",
)

# }}}
